package com.leyou.gateway.scheduler;

import com.leyou.auth.client.AuthClient;
import com.leyou.gateway.config.JwtProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

/**
 * 服务token定时任务申请类
 */
@Component
@Slf4j
public class AppTokenScheduler {
    @Autowired
    private AuthClient authClient;

    @Autowired
    private JwtProperties jwtProps;

    //用于存储当前服务的服务token
    private String appToken;

    /**
     * SpringTask只支持6位日历表达式，quartz支持7位，最后一位是年
     * cron表达式（日历表达式）
     *  cron表达式的语法：秒 分 时 日 月 周
     */
/**
 *  从0秒开始，每隔6秒钟执行一次，因为天用了“*”，那么周只能用“？”
    @Scheduled(cron = "0/6 * * * * ?")
    public void cronJob(){

    }
*/

    /**
     * token时间刷新间隔=1天
     */
    private static final long TOKEN_REFRESH_INTERVAL = 86400000L;

    /**
     * token获取失败后重试的时间间隔=10秒
     */
    private static final long TOKEN_RETRY_INTERVAL = 10000L;

    /**
     * 定时任务服务token的方法
     */
    // 这里使用的是固定频率（单位：毫秒）
    @Scheduled(fixedRate = TOKEN_REFRESH_INTERVAL)
    public void appToken(){

        while(true){
            // 1.远程调用获取服务token的方法
            try {
                appToken = authClient.authorization(
                        jwtProps.getApp().getServiceName(),
                        jwtProps.getApp().getSecret()
                );
                log.info("【网关微服务鉴权】"+jwtProps.getApp().getServiceName());

                // 如果token获取成功则退出循环
                break;
            } catch (Exception e) {
                e.printStackTrace();
                log.error("【网关微服务】获取服务token失败,原因:" + e.getMessage());
                //等待完后之后再重试
                try {
                    Thread.sleep(TOKEN_RETRY_INTERVAL);
                } catch (InterruptedException interruptedException) {
                    interruptedException.printStackTrace();
                }
            }
        }
    }
    /**
     * 该方法提供给外部获取当前服务token
     */
    public String getAppToken(){
        return appToken;
    }
}
